#!/bin/bash
# -----------------------------------------------
# // Only the first half (0x00 - 0x7f) is usable
#   uint8_t sizeOf;                   // Number of data bytes used in the writable data portion.  This is 26 today.
#   uint8_t topLevelSerialNumber[25]; // Null terminated alpha-numeric serial number
#   uint8_t unused[101];              // Unused bytes are available for future use
#   uint8_t checkSum;                 // Checksum of the first 127 bytes in the structure
# -----------------------------------------------

MYPATH=$(dirname $0)
EEPROM_PATH="/sys/bus/i2c/drivers/at24/2-0050/eeprom"
FRAM_PATH="/sys/bus/i2c/drivers/at24/3-0050/eeprom"
DEVICE=$EEPROM_PATH
TEMP_BIN="/tmp/eeprom.bin"
TEMP_BIN_WITH_CHECKSUM=${TEMP_BIN}-checksum
TOTAL_SIZE=128
# 24=25-1(NULL char)
SN_MAX_SIZE=24
# 26=1(sizeOf)+25(topLevelSerialNumber)                             
DATA_SIZE=$((1+$SN_MAX_SIZE+1)) 
SN_DATA=""


show_help()
{
        echo -e \
"Usage:\n\
 $0 [options]\n\n\
Write SN to EEPROM or FRAM\n\n\
Options:\n\
 -i <SN>	 	Input SN data\n\
 -o <E|F>		Save to E:EEPROM, F:FRAM (default:EEPROM)\n"
}

# A POSIX variable                                                             
OPTIND=1         # Reset in case getopts has been used previously in the shell.
                                                                               
while getopts "i:o:h?" opt; do                                                 
        case "$opt" in                                                         
        i)                                         
                SN_DATA=$OPTARG
                ;;
	o)
		if [[ "$OPTARG" = "F" ]]; then
			DEVICE=$FRAM_PATH
		fi
		;;                                 
        h|\?)                                      
                show_help                          
                exit 0                                                         
                ;;                                                             
        esac                                                                   
done

# Check inpurt argument
if [[ "$SN_DATA" = "" ]]; then
	echo "Error: SN cannont empty"
	exit 1
fi

SN_LENGTH=${#SN_DATA}
if [[ "$SN_LENGTH" -gt "$SN_MAX_SIZE" ]]; then
	echo "Error: SN is too long. Max length is $SN_MAX_SIZE"
	exit 1
fi

#LENGTH=$(stat -c%s /tmp/SN_DATA)
#echo "DEVICE=$DEVICE"
#echo "SN=$SN_DATA"
#echo "SN_LENGTH=$SN_LENGTH"

# Create temp bin file
rm -f $TEMP_BIN > /dev/null
rm -f $TEMP_BIN_WITH_CHECKSUM > /dev/null
#echo $TEMP_BIN
#echo $TEMP_BIN_WITH_CHECKSUM

# Create a temp file with data
# Write sizeOf
tmp=$(printf '%x' $DATA_SIZE)
echo -n -e "\\x$tmp" > $TEMP_BIN
# Write SN and a null character
echo -n -e $SN_DATA >> $TEMP_BIN
echo -n -e '\x0' >> $TEMP_BIN 

# Fill 0xff in the remaining space
count=$(($SN_LENGTH+2))
file_end=$(($TOTAL_SIZE-1))
while [[ $count -lt "$file_end" ]]
do
	count=$(($count+1))
	echo -n -e '\xff' >> $TEMP_BIN
done

# checksum
# The command calculates the checksum from the input file 
# and creates a new file has the checksum at the end of the input file. 
$MYPATH/eeprom-checksum $TEMP_BIN > /dev/null

# Write 128-bytes file to EEPROM
if [[ -f $TEMP_BIN_WITH_CHECKSUM ]]; then
	if [[ $(stat -c%s $TEMP_BIN_WITH_CHECKSUM) -eq "TOTAL_SIZE" ]]; then
		dd if=$TEMP_BIN_WITH_CHECKSUM of=$DEVICE bs=1 count=$TOTAL_SIZE > /dev/null
		echo "SN set successed"
	else
		echo "Error: Totoal Size is not 128 bytes"
		echo "FAIL"
	fi
else
	echo "Error: $TEMP_BIN_WITH_CHECKSUM is not found"
	echo "FAIL"
fi
